(require* sketch/parse/rule/util)


(defrule rectangle-line
    "rectangle = line, line, line, line"
    ?f1 <- (shape (name "Line") (obj ?l1))
    ?f2 <- (shape (name "Line") (obj ?l2&~?l1))
    ?f3 <- (shape (name "Line") (obj ?l3&~?l2&~?l1))
    ?f4 <- (shape (name "Line") (obj ?l4&~?l3&~?l2&~?l1))
	(test (call ShapePredicate joinsLineLine ?l1 ?l2))
	(test (call ShapePredicate joinsLineLine ?l2 ?l3))
	(test (call ShapePredicate joinsLineLine ?l3 ?l4))
  	(test (call ShapePredicate joinsLineLine ?l4 ?l1))
    (test (call ShapePredicate horizontalLine ?l1))
    (test (call ShapePredicate parallelLineLine ?l1 ?l3))
    (test (call ShapePredicate orthogonalLineLine ?l1 ?l2))
    (test (call ShapePredicate orthogonalLineLine ?l1 ?l4))
    (test (call ShapePredicate abovePointPoint (?l1 getCenter) (?l3 getCenter)))
    (test (call ShapePredicate leftPointPoint (?l4 getCenter) (?l2 getCenter)))
    =>
    (printout "recognize rectangle = line, line, line, line")
    (bind ?sh (new Rectangle))
    (?sh setWidth (?l1 length))
    (?sh setHeight (?l4 length))
    (?sh setRefPoint (?l1 getCommonPointTo ?l4))
    (retract ?f1)
    (retract ?f2)
    (retract ?f3)
    (retract ?f4)
    (assert (shape
            (name "Rectangle")
            (obj ?sh)
            (children ?l1 ?l2 ?l3 ?l4)))
    (recognize ?sh (list-children (create$ ?l1 ?l2 ?l3 ?l4))))

(defrule triangle-line
    "triangle = line, line, line"
    ?f1 <- (shape (name "Line") (obj ?l1))
    ?f2 <- (shape (name "Line") (obj ?l2&~?l1))
    ?f3 <- (shape (name "Line") (obj ?l3&~?l2&~?l1))
    (test (call ShapePredicate joinsLineLine ?l1 ?l2))
    (test (call ShapePredicate joinsLineLine ?l2 ?l3))
    (test (call ShapePredicate joinsLineLine ?l3 ?l1))
    (test (not (call ShapePredicate nearPointPoint
                (?l1 getCommonPointTo ?l2)
                (?l2 getCommonPointTo ?l3))))
    =>
    (printout "recognize triangle = line, line, line")
    (bind ?sh (new Triangle))
    (?sh setP1 (?l1 getEndPointTo ?l2))
    (?sh setP2 (?l2 getEndPointTo ?l3))
    (?sh setP3 (?l3 getEndPointTo ?l1))
    (retract ?f1)
    (retract ?f2)
    (retract ?f3)
    (assert (shape
            (name "Triangle")
            (obj ?sh)
            (children ?l1 ?l2 ?l3)))
    (recognize ?sh (list-children (create$ ?l1 ?l2 ?l3))))
